﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Reborn_Server.App1AppHandler;
using App1AppHandler;
using Reborn_WorldServer;

namespace Reborn_Server.App1AppHandler
{
    public class Spell_WindPush : AreaSpell
    {
        public Spell_WindPush()
        {
            spellTimer.Interval = 900;
        }

        public void PositionCast(SpellIcon _spellIcon, CreatureBase myCreatureBase, int CastLevel, int MapX, int MapY)
        {
            List<MapItem> MapItemsWithin12;
            base.InitializeInstantCast(myCreatureBase, CastLevel, _spellIcon, MapX, MapY, out MapItemsWithin12);

            mainCast(myCreatureBase, CastMapX, CastMapY);
        }

        public void CreatureCast(SpellIcon _spellIcon, CreatureBase myCreatureBase, int CastLevel, int MapX, int MapY)
        {
            List<MapItem> MapItemsWithin12;
            base.InitializeInstantCast(myCreatureBase, CastLevel, _spellIcon, MapX, MapY, out MapItemsWithin12);

            myCreatureBase.Mana = myCreatureBase.Mana - _spellIcon.ManaCost;
            myCreatureBase.WarmSpell = null;

            mainCast(myCreatureBase, CastMapX, CastMapY);
        }

        private string direction = "";
        private void mainCast(CreatureBase castingCreature, int castMapX, int castMapY)
        {
            int randomDirection = Managers.GameHandler.random.Next(0, 4);

            if (randomDirection == 0)
            {
                direction = "N";
            }
            else if (randomDirection == 1)
            {
                direction = "E";
            }
            else if (randomDirection == 2)
            {
                direction = "S";
            }
            else if (randomDirection == 3)
            {
                direction = "W";
            }

            List<Character> charactersToUpdate = new List<Character>();
            foreach (MapItem mapItem in castingCreature.currentMapItem.mapItemsWithin8)
            {
                //Horizontal
                if (mapItem.MapY == castingCreature.MapY && Math.Abs(mapItem.MapX - castingCreature.MapX) <= 1 && (direction == "N" || direction == "S") && mapItem.Motion > 0)
                {
                    base.MapItems.Add(mapItem);
                    mapItem.SpellLayer1.Add(this);
                }
                //Vertical
                else if (mapItem.MapX == castingCreature.MapX && Math.Abs(mapItem.MapY - castingCreature.MapY) <= 1 && (direction == "E" || direction == "W") && mapItem.Motion > 0)
                {
                    base.MapItems.Add(mapItem);
                    mapItem.SpellLayer1.Add(this);
                }
                else
                {
                    foreach (CreatureBase creatureBase in mapItem.CreaturesBases)
                    {
                        if (creatureBase is Character && creatureBase.HP > 0)
                            charactersToUpdate.Add((Character)creatureBase);
                    }
                }
            }

            List<string> moveList = new List<string>();
            moveList.Add(direction);

            if (base.MapItems.Count == 0)
                return;

            List<Character> charactersToMove = new List<Character>();
            foreach (MapItem mapItem in base.MapItems)
            {
                foreach (CreatureBase creatureBase in mapItem.CreaturesBases)
                {
                    if (creatureBase is Character && creatureBase.HP > 0)
                        charactersToMove.Add((Character)creatureBase);
                }
            }

            foreach (Character character in charactersToMove)
                Managers.GameHandler.ChangePosition(character, moveList, -1, false, true);

            foreach (Character character in charactersToUpdate)
                character.AddMapItems(base.MapItems, false);


            //Start Spell Timer
            spellTimer.Start();
        }

        protected override void SpellTimer_Expired(object source, System.Timers.ElapsedEventArgs e)
        {
            //Get MapLock
            LockItem MapLock = Managers.GameHandler.GetLockItem(MapID, Instance);
            
            //Lock MapLock
            lock (MapLock.LockObj)
            {
                if (base.MapItems.Count == 0)
                    return;

                //Record a list of mapitems to update, we will be moving the spell so we'll update its current positions and its new positions
                List<MapItem> mapItemsToUpdate = new List<MapItem>();
                
                List<MapItem> oldMapItems = new List<MapItem>();

                //Record the old positions
                foreach (MapItem mapItem in base.MapItems)
                {
                    mapItemsToUpdate.Add(mapItem);
                    oldMapItems.Add(mapItem);
                }

                //Clean up the old positions
                while (base.MapItems.Count > 0)
                {
                    base.MapItems[0].SpellLayer1.Remove(this);
                    base.MapItems.RemoveAt(0);
                }

                List<Character> charactersToUpdate = new List<Character>();

                foreach (MapItem mapItem in oldMapItems[0].mapItemsWithin8)
                {
                    bool recordCharacters = true;
                    if (mapItem.Motion > 0)
                    {
                        foreach (MapItem currentMapItem in oldMapItems)
                        {
                            if (direction == "N" && mapItem.MapX == currentMapItem.MapX && mapItem.MapY == currentMapItem.MapY - 1)
                            {
                                base.MapItems.Add(mapItem);
                                mapItemsToUpdate.Add(mapItem);
                                mapItem.SpellLayer1.Add(this);
                                recordCharacters = false;
                            }
                            else if (direction == "S" && mapItem.MapX == currentMapItem.MapX && mapItem.MapY == currentMapItem.MapY + 1)
                            {
                                base.MapItems.Add(mapItem);
                                mapItemsToUpdate.Add(mapItem);
                                mapItem.SpellLayer1.Add(this);
                                recordCharacters = false;
                            }
                            else if (direction == "E" && mapItem.MapY == currentMapItem.MapY && mapItem.MapX == currentMapItem.MapX + 1)
                            {
                                base.MapItems.Add(mapItem);
                                mapItemsToUpdate.Add(mapItem);
                                mapItem.SpellLayer1.Add(this);
                                recordCharacters = false;
                            }
                            else if (direction == "W" && mapItem.MapY == currentMapItem.MapY && mapItem.MapX == currentMapItem.MapX - 1)
                            {
                                base.MapItems.Add(mapItem);
                                mapItemsToUpdate.Add(mapItem);
                                mapItem.SpellLayer1.Add(this);
                                recordCharacters = false;
                            }
                        }
                    }
                    if (recordCharacters)
                    {
                        foreach (CreatureBase creatureBase in mapItem.CreaturesBases)
                        {
                            if (creatureBase is Character)
                                charactersToUpdate.Add((Character)creatureBase);
                        }
                    }
                }

                List<string> moveList = new List<string>();
                moveList.Add(direction);

                List<Character> charactersToMove = new List<Character>();
                foreach (MapItem mapItem in base.MapItems)
                {
                    foreach (CreatureBase creatureBase in mapItem.CreaturesBases)
                    {
                        if (creatureBase is Character && creatureBase.HP > 0)
                            charactersToMove.Add((Character)creatureBase);
                    }
                }

                foreach (Character character in charactersToMove)
                    Managers.GameHandler.ChangePosition(character, moveList, -1, false, true);

                foreach (Character character in charactersToUpdate)
                    character.AddMapItems(mapItemsToUpdate, false);


                //Start Spell Timer
                spellTimer.Start();
            }
        }

    }
}
